import api from "@/api";
import SparkMD5 from "spark-md5"; // 引入SparkMD5用于计算文件的MD5值

//文件上传返回数据
let exportData = {
    selectedFile: null,// 用户选择的文件
    uploadProgress: 0, // 上传进度
    requestPool: [], // 请求池，存储待上传的切片信息
    chunkCount: 0,// 文件切片总数
    uploadedChunksCount: 0,// 已上传的切片数量
    fileVo: null, //文件信息
}

/**
 * 处理文件选择事件
 * @param event
 * @returns {Promise<*>}
 */
let handleFileChange = async function (event) {
    console.log(event)
    exportData.selectedFile = event.target.files[0];
    if (!exportData.selectedFile) return; // 未选择文件则返回
    // 可以在这里添加文件格式校验
    const fileHash = await computeFileHash(exportData.selectedFile); // 计算文件hash
    const checkFileData = await checkFile(fileHash); // 检查文件是否需要上传
    if (checkFileData && checkFileData.num === checkFileData.count) {
        exportData.uploadProgress = 100; // 直接设置进度为100%
        return clearData();
    }
    await sliceFileAndUpload(fileHash, checkFileData); // 切片并上传
    console.log("b")
    return clearData();
};
/**
 * 数据清理
 * @returns {any}
 */
let clearData = function () {
    let dataValue = JSON.parse(JSON.stringify(exportData));
    exportData = {
        selectedFile: null,// 用户选择的文件
        uploadProgress: 0, // 上传进度
        requestPool: [], // 请求池，存储待上传的切片信息
        chunkCount: 0,// 文件切片总数
        uploadedChunksCount: 0,// 已上传的切片数量
        fileVo: null, //文件信息
    }
    return dataValue;
};
/**
 * 计算文件的MD5
 * @param file
 * @returns {Promise<unknown>}
 */
let computeFileHash = async function (file) {
    return await new Promise(async (resolve) => {
        const spark = await  new SparkMD5.ArrayBuffer();
        const fileReader = await new FileReader();
        fileReader.onload = async (e) => {
            spark.append(e.target.result);
            const hash = spark.end();
            resolve(hash); // 返回计算得到的hash值
        };
        fileReader.readAsArrayBuffer(file);
    });
};
/**
 * 检查文件是否已经上传过
 * @param fileHash
 * @returns {Promise<*>}
 */
let checkFile = async function (fileHash) {
    // 应替换为真实的API调用来检查文件状态
    let res = await api.system.getFileStatus({hashValue: fileHash})
    if (res.code === 200) {
        exportData.fileVo = res.data;
        // 模拟返回值
        return res.data;
    }
};
/**
 * 切片并准备上传
 * @param fileHash
 * @param checkFileData
 * @returns {Promise<void>}
 */
let sliceFileAndUpload = async function (fileHash, checkFileData) {
    const chunkSize = 5 * 1024 * 1024; // 切片大小，这里是10MB
    if (exportData.selectedFile.size <= chunkSize) {
        exportData.chunkCount = 1;
        let chunk = exportData.selectedFile;
        exportData.requestPool.push({chunk, index: 0})
    } else {
        exportData.chunkCount = Math.ceil(exportData.selectedFile.size / chunkSize); // 计算总切片数
        exportData.uploadProgress = 0; // 重置上传进度
        for (let i = 0; i < exportData.chunkCount; i++) {
            if (checkFileData && i <= checkFileData.num) continue; // 跳过已上传的切片
            const chunk = exportData.selectedFile.slice(i * chunkSize, (i + 1) * chunkSize); // 获取切片
            exportData.requestPool.push({chunk, index: i}); // 加入请求池
        }
    }

    //console.log(exportData.requestPool)
    await processPool(fileHash); // 开始处理请求池
};
/**
 * 处理请求池中的切片上传
 * @param fileHash
 * @returns {Promise<void>}
 */
let processPool = async function (fileHash) {
    for (let i = 0; i < exportData.requestPool.length; i++) {
        let {chunk, index} = exportData.requestPool[i];
        await uploadChunk(chunk, fileHash, index) // 上传切片
            .then(() => {
            }).catch(e => {
                exportData.requestPool.push({chunk, index: index});
            });
        exportData.uploadedChunksCount++; // 更新已上传切片数量
        let value = (index + 1) / exportData.chunkCount * 100
        exportData.uploadProgress = parseFloat(value).toFixed(2); // 更新上传进度
        console.log("f")
    }
};
/**
 * 上传单个切片
 * @param chunk
 * @param fileHash
 * @param index
 * @returns {Promise<void>}
 */
let uploadChunk = async function (chunk, fileHash, index) {
    const formData = new FormData();
    formData.append("file", chunk);
    formData.append("hashValue", fileHash);
    formData.append("num", index + 1);
    formData.append("count", exportData.chunkCount);
    formData.append("fileName", exportData.selectedFile.name);
    // 替换为真实的上传URL，并根据需要实现onUploadProgress
    let res = await api.system.largeFilSlicingUpload(formData);
    if (res.code === 200) {
        exportData.fileVo = res.data;
    }

};
/**
 * 通知服务器合并切片
 * @param fileHash
 * @returns {Promise<void>}
 */
let notifyServerToMerge = async function (fileHash) {
    // 通知服务器合并切片，应替换为真实的合并API调用
    console.log(`通知服务器将文件与哈希合并: ${fileHash}`);
};

export {
    exportData,
    handleFileChange,
    computeFileHash
}